package test.entry;


import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters;
import test.utility.Randomly.StringGenerationStrategy;

import java.util.ArrayList;
import java.util.List;

/*
 * @ 2022-10-17
 * 程序支持的参数说明
 */
@Parameters(separators = "=", commandDescription = "Options applications applicable")
public class MainOptions {
    @Parameter(names = {"--help", "-h"}, description = "Lists all supported options and commands")
    private boolean help = false;
    @Parameter(names = {"--config", "-c"}, description = "Specifies the run properties file")
    private String config = "run.properties";
    @Parameter(names = {"--exec-sql", "-s"}, description = "Only execute sqlfile, not gen sql")
    private String sqlfile = null;

    //测试全部
    @Parameter(names = {"--test-all", "-a"}, description = "Only execute sqlfile, not gen sql")
    private boolean testAllFlag = false;

    @Parameter(names = {"--disable-test", "-d"}, description = "Only execute sqlfile, not gen sql")
    private List<String> disableFeatures = new ArrayList<String>();

    @Parameter(names = {"--test-group", "-g"}, description = "Specifies whether to test grouby-statement")
    private boolean testGroup = false;

    @Parameter(names = {"--test-group-cube",}, description = "Specifies whether to test grouby-statement")
    private boolean testGroupbycube = false;

    @Parameter(names = {"--test-group-rollup",}, description = "Specifies whether to test grouby-statement")
    private boolean testGroupbyRollup = false;

    //测试GROUPING SETS
    @Parameter(names = { "--test-group-groupingsets"} , description = "Specifies whether to test groupby grouping sets")
    private boolean testGroupbyGroupingSets = false;

    //测试join
    @Parameter(names = { "--test-join","-j"} , description = "Specifies whether to test join")
    private boolean testJoin = false;

    @Parameter(names = {"--test-having"}, description = "Specifies whether to test having-statement")
    private boolean testHaving = false;
    @Parameter(names = {"--test-limit", "-1"}, description = "Specifies whether to test limit-statement or offset-statement")
    private boolean testLimit = false;
    @Parameter(names = {"--test-with", "-w"}, description = "Specifies whether to test with-statement")
    private boolean testWith = false;

    @Parameter(names = { "--test-unions" , "-u"} , description = "Specifies whether to test unions-statement")
    private boolean testUnions = false;
    @Parameter(names = {"--test-hint", "-i"}, description = "Specifies whether to test hint")
    private boolean testHint = false;
    @Parameter(names = {"--test-ifun", "-f"}, description = "Specifies whether to test iFunction")
    private boolean testIFun = false;
    @Parameter(names = {"--test-order", "-o"}, description = "Specifies whether to test order")
    private boolean test0rder = false;

    @Parameter(names = {"--test-top", "-t"}, description = "Specifies whether to test order")
    private boolean testTop = false;

    @Parameter(names = {"--test-rownum"}, description = "Specifies whether to test order")
    private boolean testRownum = false;

    @Parameter(names = {"--correlated-subquery", "-r"}, description = "Specifies whether to test Correlated Subquery")
    private boolean testCorrelatedSubquery = false;
    @Parameter(names = {"--random-seed"}, description = "A seed value != -1 that can be set to the randomly-seed Randomly")
    private long randomSeed = -1;

    @Parameter(names = "--random-string-range", description = "Select the random-string generation"
            + " approach. 0:NUMERIC,1:ALPHANUMERIC,2:ALPHANUMERIC_SPECIALCHAR,3:SOPHISTICATED. default value is 1")
    private int randomStringRange = 1;
    @Parameter(names = "--string-constant-max-length", description = "Specify the maximum-length of generated string constants")
    private int maxStringConstantLength = 10;
    @Parameter(names = "--use-constant-caching", description = "Specifies whether constants"
            + " should be cached and re-used with a certain probability", arity = 1)
    private boolean useConstantCaching = true;
    @Parameter(names = "--constant-cache-size", description = "Specifies the size of the constant cache."
            + "This option only takes effect when constant caching is enabled")
    private int constantCacheSize = 100;

    public boolean isHelp() {
        return help;
    }

    public String getConfigFile() {
        return config;
    }

    public String getSqlFile() {
        return sqlfile;
    }

    public boolean testAll() {
        return testAllFlag;

    }

    public List<String> getDisabledFeatures() {
        return disableFeatures;
    }

    public boolean testGroupby() {
        return testGroup||testGroupbyRollup||testGroupbycube;
    }

    public boolean testGroupbyRollup() {
        return testGroupbyRollup;
    }

    public boolean testGroupbyCube() {
        return testGroupbycube;
    }

    public boolean testGroupbyGroupingSets(){
        return testGroupbyGroupingSets;
    }

    public boolean testJoin(){
        return testJoin;
    }
    public boolean testHaving() {
        return testHaving;
    }

    public boolean testLimit() {
        return testLimit;
    }

    public boolean testWith() {
        return testWith;
    }

    public boolean testUnions(){
        return testUnions;
    }

    public boolean testHint() {
        return testHint;
    }

    public boolean testIFun() {
        testIFun=false;
        return testIFun;
    }

    public boolean testOrder() {
        return test0rder;
    }

    public boolean testTop() {
        return testTop;
    }

    public boolean testRownum() {
        return testRownum;
    }

    public boolean testCorrelatedSubquery() {
        if (testAllFlag) {
            testCorrelatedSubquery=true;
            for (String feature:disableFeatures){
                if (feature.equalsIgnoreCase("correlated")){
                    testCorrelatedSubquery=false;
                    break;
                }
            }
        }
        return testCorrelatedSubquery;
    }

    public long getRandomSeed() {
        return randomSeed;
    }

    public StringGenerationStrategy getRandomStringGenerationStrategy() {
        switch (randomStringRange) {
            case 0:
                return StringGenerationStrategy.NUMERIC;
            case 2:
                return StringGenerationStrategy.ALPHANUMERIC_SPECIALCHAR;
            case 3:
                return StringGenerationStrategy.SOPHISTICATED;
            case 1:
            default:
                return StringGenerationStrategy.ALPHANUMERIC;
        }
    }

    public int getMaxStringConstantLength() {
        return maxStringConstantLength;
    }

    public boolean useConstantCaching() {
        return useConstantCaching;
    }

    public int getConstantCacheSize() {
        return constantCacheSize;
    }
}